package com.mk.websocket;

import com.mk.entity.Chat;
import com.mk.mq.MessageSender;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mk.service.ChatRedisService;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 聊天的WebSocket服务
 */
@ServerEndpoint("/chat/{userId}")
@Component
public class ChatWebSocketServer {
    private static final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
    private static MessageSender messageSender;
    private static ChatRedisService chatRedisService;
    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 由于 @ServerEndpoint 不能直接注入 Spring Bean，需要使用静态方法手动注入
    public static void setMessageSender(MessageSender sender) {
        messageSender = sender;
    }

    //手动注入Redis服务
    public static void setChatRedisService(ChatRedisService service) {
        chatRedisService = service;
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        sessions.put(userId, session);
        System.out.println("用户 " + userId + " 连接成功！");
    }

    @OnMessage
    public void onMessage(String messageJson, @PathParam("userId") String senderId) throws IOException {
        Chat chat = objectMapper.readValue(messageJson, Chat.class);
        chat.setSendUserId(Long.valueOf(senderId));

        //存入Redis
        chatRedisService.saveMessage(chat);

        // 将消息发送到 RabbitMQ 进行处理
        messageSender.sendMessage(chat);
    }

    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        sessions.remove(userId);
        System.out.println("用户 " + userId + " 断开连接");
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    // 服务器主动推送消息
    public static void sendToUser(String userId, String message) throws IOException {
        Session session = sessions.get(userId);
        if (session != null && session.isOpen()) {
            session.getBasicRemote().sendText(message);
        }
    }
}

